/*
* 程序名: clientdemo1.cpp，此程序用于演示socket的客户端
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>

using namespace std;

int main(int argc, char *argv[])
{
	if(argc!=3)
	{
		cout << "Using:./clientdemo1 服务端的IP 服务端的端口\nExample:./clientdemo1 192.168.101.139 5005\n\n";
		return -1;
	}

	// 第一步：创建客户端的socket
	int sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd == -1)
	{
		perror("socket"); 
		return -1;
	}

	// 第二步：向服务器发起连接请求
	struct hostent *h;	//用于存放服务端ip的结构体
	if ( (h = gethostbyname(argv[1])) == 0) //把字符串格式的ip转换成结构体
	{
		cout << "gethostbyname failed.\n" << endl;
		return -1;
	}

	struct sockaddr_in servaddr;
	memset(&servaddr,0,sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	//servaddr.sin_addr.s_addr = inet_addr("119.147.41.220");
	memcpy(&servaddr.sin_addr, h->h_addr_list[0], h->h_length); //指定服务端的ip地址。
	servaddr.sin_port = htons(atoi(argv[2]));	// 指定服务端的通信端口。

	cout << "ip: " << servaddr.sin_addr.s_addr << "port: " << servaddr.sin_port << endl;
	
	errno = 0;
	if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr))!=0)
	{

		printf("Error code: %d, error :%s\n", errno, strerror(errno));
		perror("connect");
		close(sockfd);
		return -1;
	}
	
	//第三步：与服务端通信，客户发送一个请求报文后等待服务端恢复，收到回复后，再发送下一个请求报文。
	char buffer[1024];
	for(int ii=0;ii<3;ii++)
	{
		int iret;
		memset(buffer,0,sizeof(buffer));
		sprintf(buffer,"这是第%d个超级女生，编号%03d。", ii+1, ii+1);
		
		if( (iret = send(sockfd,buffer,strlen(buffer),0)) <= 0)
		{
			perror("send");
			break;
		}
		cout << "发送：" << buffer << endl;

		memset(buffer, 0, sizeof(buffer));
		// 接收服务端的回应报文，如果服务端没有回应报文，recv()函数会阻塞等待。
		if( (iret = recv(sockfd,buffer, sizeof(buffer),0) <= 0))
		{
			cout << "iret=" << iret << endl;
			break;
		}
		cout << "接收：" << buffer << endl;

		sleep(1);
	}
	
	// 第四步：关闭socket，释放资源。
	close(sockfd);

}
